class AuthenticationManager {
public:
    AuthenticationManager(int timeToLive)
        : _timeToLive(timeToLive)
    {}

    void generate(string tokenId, int currentTime) {
        hash.insert(make_pair(tokenId, currentTime + _timeToLive));
    }

    void renew(string tokenId, int currentTime) {
        if (hash.find(tokenId) == hash.end())
            return;
        if (hash[tokenId] <= currentTime)
            hash.erase(tokenId);
        else
            hash[tokenId] = currentTime + _timeToLive;
    }

    int countUnexpiredTokens(int currentTime) {
        int count = 0;
        auto it = hash.begin();
        while (it != hash.end())
        {
            if (it->second <= currentTime)
            {
                it = hash.erase(it);
            }
            else
            {
                count++;
                ++it;
            }
        }
        return count;
    }

    int _timeToLive;
    unordered_map<string, int> hash;
};

/**
 * Your AuthenticationManager object will be instantiated and called as such:
 * AuthenticationManager* obj = new AuthenticationManager(timeToLive);
 * obj->generate(tokenId,currentTime);
 * obj->renew(tokenId,currentTime);
 * int param_3 = obj->countUnexpiredTokens(currentTime);
 */